using Microsoft.AspNetCore.Mvc;
using SPI.AgentServer.Models;
using SPI.AgentServer.Services.Orchestration;
using Swashbuckle.AspNetCore.Annotations;

namespace SPI.AgentServer.Controllers;

/// <summary>
/// 智能查询服务主控制器
/// </summary>
[ApiController]
[Route("api/agent")]
[Produces("application/json")]
[SwaggerTag("核心功能 - 处理自然语言查询请求")]
public class AgentController : ControllerBase
{
    private readonly IQueryOrchestrator _orchestrator;
    private readonly ILogger<AgentController> _logger;
    private static readonly SemaphoreSlim _requestSemaphore = new SemaphoreSlim(20, 20); // 最多20个并发请求（低并发场景足够）

    public AgentController(IQueryOrchestrator orchestrator, ILogger<AgentController> logger)
    {
        _orchestrator = orchestrator;
        _logger = logger;
    }

    /// <summary>
    /// 执行自然语言查询
    /// </summary>
    /// <remarks>
    /// 接受中文或英文的自然语言输入，自动转换为 SQL 并执行。
    /// 
    /// 示例查询：
    /// - "用户表有多少条记录"
    /// - "查看今天的订单数量"
    /// - "统计每个部门的平均工资"
    /// - "显示销售额前10的产品"
    /// </remarks>
    /// <param name="request">查询请求对象</param>
    /// <returns>包含数据、摘要和元信息的响应</returns>
    /// <response code="200">查询成功</response>
    /// <response code="400">请求无效或查询失败</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost("query")]
    [ProducesResponseType(typeof(QueryResponse), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(QueryResponse), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
    [SwaggerOperation(
        Summary = "执行自然语言查询",
        Description = "将自然语言转换为 SQL 并执行，返回结果和自然语言摘要",
        OperationId = "ExecuteNaturalLanguageQuery",
        Tags = new[] { "核心功能" }
    )]
    public async Task<IActionResult> Query([FromBody] QueryRequest request)
    {
        if (string.IsNullOrWhiteSpace(request.Query))
        {
            return BadRequest(new QueryResponse
            {
                Success = false,
                Errors = new List<string> { "Query cannot be empty" },
                Summary = "请提供查询内容"
            });
        }

        // 【并发控制】限制同时处理的请求数量，防止资源耗尽
        if (!await _requestSemaphore.WaitAsync(TimeSpan.FromSeconds(10)))
        {
            _logger.LogWarning("请求队列已满，拒绝请求");
            return StatusCode(503, new QueryResponse
            {
                Success = false,
                Errors = new List<string> { "服务繁忙" },
                Summary = "当前请求过多，请稍后重试"
            });
        }

        try
        {
            _logger.LogInformation("Received query from session {SessionId}: {Query}", 
                request.SessionId ?? "anonymous", request.Query);

            // 【关键】为每个请求设置最大超时时间（60秒），并关联HTTP请求的取消
            using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60));
            using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, HttpContext.RequestAborted);
            
            var response = await _orchestrator.ProcessQueryAsync(request, linkedCts.Token);

            if (response.Success)
            {
                return Ok(response);
            }
            else
            {
                return BadRequest(response);
            }
        }
        catch (OperationCanceledException)
        {
            _logger.LogError("查询超时（60秒）");
            return StatusCode(504, new QueryResponse
            {
                Success = false,
                Errors = new List<string> { "请求超时" },
                Summary = "查询超时，请稍后重试或简化查询条件"
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Unhandled error processing query");
            return StatusCode(500, new QueryResponse
            {
                Success = false,
                Errors = new List<string> { "Internal server error" },
                Summary = "服务器内部错误，请稍后重试"
            });
        }
        finally
        {
            // 释放信号量，允许下一个请求进入
            _requestSemaphore.Release();
        }
    }

    /// <summary>
    /// 健康检查
    /// </summary>
    /// <remarks>
    /// 用于检查服务是否正常运行
    /// </remarks>
    /// <returns>服务状态信息</returns>
    [HttpGet("health")]
    [ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
    [SwaggerOperation(
        Summary = "健康检查",
        Description = "检查服务状态",
        OperationId = "HealthCheck",
        Tags = new[] { "系统状态" }
    )]
    public IActionResult Health()
    {
        return Ok(new
        {
            status = "healthy",
            timestamp = DateTime.UtcNow,
            service = "SPI.AgentServer"
        });
    }
}
